/**
现给定一个函数 fn，一个参数数组 args 和一个时间间隔 t，返回一个取消函数 cancelFn。
在经过 cancelTimeMs 毫秒的延迟后，将调用返回的取消函数 cancelFn。
setTimeout(cancelFn, cancelTimeMs)
函数 fn 应立即使用参数 args 调用，然后每隔 t 毫秒调用一次，
直到在 cancelTimeMs 毫秒时调用 cancelFn。

输入：fn = (x) => x * 2, args = [4], t = 35, cancelT = 190
输出：
[
   {"time": 0, "returned": 8},
   {"time": 35, "returned": 8},
   {"time": 70, "returned": 8},
   {"time": 105, "returned": 8},
   {"time": 140, "returned": 8},
   {"time": 175, "returned": 8}

 */
var cancellable = function (fn, args, t) {
  let isCancelled = false;
  fn(...args); // 立即执行
  let timer = setInterval(() => (isCancelled ? clearInterval(timer) : fn(...args)), t);
  return function () {
    isCancelled = true;
  };
};

/**
 * setInterval 和 clearInterval
 * 确保间隔时间和 fn 的执行时间得到适当的平衡是至关重要的
 * 使用 requestAnimationFrame 代替 setInterval 可以实现更好的性能
 */
/**
 * 间隔取消用例
 */